package com.ocp.socket.busi.device.service.impl;

import com.ocp.socket.busi.device.bean.DeviceInfo;
import com.ocp.socket.busi.device.bean.LineInfo;
import com.ocp.socket.busi.device.mapper.DeviceInfoMapper;
import com.ocp.socket.busi.device.service.IDeviceInfoService;
import com.ocp.socket.common.Constants;
import com.ocp.socket.common.bean.DevInfo;
import com.ocp.socket.common.enums.CacheKeyEnum;
import com.ocp.socket.common.enums.MsgTypeEnum;
import com.ocp.socket.common.utils.DateUtil;
import com.ocp.socket.common.utils.RedisUtil;
import com.ocp.socket.server.vo.MessageVo;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @Author : lichong
 * @description :
 * @Date Create in 13:26 2019/3/9
 * @Modified By :
 **/
@Service("deviceInfoService")
public class DeviceInfoServiceImpl implements IDeviceInfoService {
    @Autowired
    private DeviceInfoMapper deviceInfoMapper;
    @Autowired
    private RedisUtil redisUtil;

    /**
     * 获取设备信息
     * @param snNo  设备sn码
     * @return
     */
    @Override
    @Cacheable(value = "device_info",key = "#snNo", unless = "#result == null")
    public DeviceInfo getDeviceInfo(String snNo) {
        DeviceInfo deviceInfo = deviceInfoMapper.getDeviceInfoBySnNo(snNo);
        if (deviceInfo != null) {
            List<LineInfo> lineInfoList = deviceInfoMapper.getLineInfoList(snNo);
            deviceInfo.setLineInfos(lineInfoList);
        }
        return deviceInfo;
    }

    /**
     * 添加设备的在线信息
     * @param devInfo
     */
    @Override
    public void addDevInfoIntoSet(DevInfo devInfo) {
        long time = System.currentTimeMillis();
        double score = Double.valueOf(time + RandomStringUtils.randomNumeric(3));
        redisUtil.zAdd(CacheKeyEnum.DEVICE_ONLINE_SET.getCacheKey(), devInfo, score);
    }

    /**
     * 检查是否是新数据，并且把过期的时间过滤，未来的时间过滤
     *      过期时间是前7天的数据判断为过期时间
     *      未来数据是大于当前时间为未来数据
     * @param messageVo
     */
    @Override
    public boolean checkNewData(MessageVo messageVo) {
        //转换字符串时间为时间搓
        Long dateTime = DateUtil.getStrTimeStamp(messageVo.getDataTime());
        if (dateTime == null) {
            messageVo.setReturnCode(Constants.RETURN_CODE_FAIL);
            messageVo.setReturnMsg("时间格式不合法");
            return false;
        }
        long now = System.currentTimeMillis();
        /*if (dateTime > now) {
            messageVo.setReturnCode(Constants.RETURN_CODE_FAIL);
            messageVo.setReturnMsg("收到未来的数据不处理");
            return false;
        }*/
        //获取设备的最新时间
        String key = CacheKeyEnum.DEVICE_NEWEST_UPLOAD_TIME.getCacheKey() + messageVo.getSn();
        long expireTime = CacheKeyEnum.DEVICE_NEWEST_UPLOAD_TIME.getExpireTime();
        Object newestTime = redisUtil.get(key);
        if (newestTime == null ) {
            /*if (dateTime < now - expireTime * 1000L) {
                messageVo.setReturnCode(Constants.RETURN_CODE_FAIL);
                messageVo.setReturnMsg("过期的数据");
                return false;
            } else {*/
                messageVo.setNewDataFlag(true);
                redisUtil.set(key, dateTime, expireTime);
            //}
        } else {
            long newestTime1 = Long.parseLong(newestTime.toString());
            if (dateTime > newestTime1) {
                messageVo.setNewDataFlag(true);
                redisUtil.set(key, dateTime, expireTime);
            } else {
                messageVo.setNewDataFlag(false);
            }
        }
        return true;
    }

    /**
     * 获取心跳停止的设备信息
     * @return
     */
    @Override
    public List<DevInfo> getStopHeartDevConInfoList() {
        List<DevInfo> infos = new ArrayList<>();
        String key = CacheKeyEnum.DEVICE_ONLINE_SET.getCacheKey();
        long now = System.currentTimeMillis();
        double startSort = Double.valueOf((now - Constants.EXPIRE_TIME_SORT - 20 * 1000) + "000");
        double endSort =  Double.valueOf((now - Constants.EXPIRE_TIME_SORT) + "000");
        //获取温度气压超多50秒停止心跳的设备信息
        Set<DevInfo> devInfos = redisUtil.zRange(key, startSort, endSort, DevInfo.class);
        String typeAirp = MsgTypeEnum.AIRP.getTypeCode(), typeTemp = MsgTypeEnum.TEMP.getTypeCode();
        if (!CollectionUtils.isEmpty(devInfos)) {
            for (DevInfo devInfo : devInfos) {
                if (typeAirp.equals(devInfo.getTypeCode())
                        || typeTemp.equals(devInfo.getTypeCode())) {
                    infos.add(devInfo);
                }
            }
        }
        //获取其他设备心跳停止超过5分钟的设备信息
        double startLong = Double.valueOf((now - Constants.EXPIRE_TIME_LONG - 100 * 1000) + "000");
        double endLong = Double.valueOf((now - Constants.EXPIRE_TIME_LONG) + "000");
        Set<DevInfo> devInfoList = redisUtil.zRange(key, startLong, endLong, DevInfo.class);
        infos.addAll(devInfoList);
        return infos;
    }

}
